package br.com.sms.action;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.struts2.ServletActionContext;

import br.com.sms.dominio.Cidade;
import br.com.sms.dominio.Destinatario;
import br.com.sms.dominio.Telefone;
import br.com.sms.enuns.SEXO;
import br.com.sms.enuns.UF;
import br.com.sms.util.Mensagens;
import br.com.sms.util.MensagensErro;
import br.com.sms.util.Obejto;

import com.opensymphony.xwork2.ActionContext;

public class CargaUsuarioAction extends Action{
	private static final long serialVersionUID = 1366903135973275232L;

	FileInputStream planilhaInputStream;

	private File upload;   
	private String uploadFileName; //nome do arquivo enviado  
	private String uploadContentType; //contexto do arquivo, imagem, txt etc...   

	private List<Obejto> posicaoColunas = new ArrayList<Obejto>();
	
	private Integer colunaNome;
	private Integer colunaCPF;
	private Integer colunaEndereco;
	private Integer colunaCidade;
	private Integer colunaUF;
	private Integer colunaCEP;
	private Integer colunaTelefone;
	private Integer colunaCelular;
	private Integer colunaEmail;
	private Integer colunaTratamento;
	private Integer colunaApelido;
	private Integer colunaSexo;
	private Integer colunaRg;
	private Integer colunaDataNascimento;
	private Integer colunaHomePage;
	private Integer colunaEmpresa;
	private Integer colunaCargo;
	private Integer colunaComplementoEndereco;
	private Integer colunaBairro;
	private Integer colunaPais;
	private Integer colunaPartidoPolitico;
	private Integer colunaTipoPessoa;
	private Integer colunaPrefixoEndereco;
	private Integer colunaNumeroEndereco;
	private Integer colunaDDDTelefone;
	private Integer colunaDDITelefone;
	private Integer colunaRamalTelefone;
	private Integer colunaDDDCelular;
	private Integer colunaDDICelular;

	private List<Obejto> obejtos;
	
	
	/**
	 * Direciona para a tela de carga de usuários e
	 * exibe as mensagens de sucesso e de erro caso existam.
	 * @return
	 */
	public String telaCargaUsuario(){
		apresentarErros();
		apresentarMensagens();
		
		posicaoColunas = new ArrayList<Obejto>();
		return TELA_CARGA_USUARIO;
	}

	/**
	 * Ler o arquivo .xls com os usuarios para popular o banco de dados
	 * @return
	 */
	public String carregarUsuarios(){
		if(validaArquivo()){
			HSSFWorkbook work;
	
			try {
				planilhaInputStream = new FileInputStream(upload);
				
				String idSessao = ServletActionContext.getRequest().getSession().getId();
				String nomeArquivo = "user-"+idSessao+".xls";
				String path = CargaUsuarioAction.class.getResource("/struts.xml").getPath().toString();
				path = path.replace("/classes/struts.xml", "/arquivo/");
				
				File arquivoSalvo = getUtilArquivo().criarArquivo((InputStream)planilhaInputStream, path, nomeArquivo);
	
				path = path.concat(nomeArquivo);
				ActionContext.getContext().getSession().put("arquivo", path);
				
				work = new HSSFWorkbook(new FileInputStream(arquivoSalvo));
				HSSFSheet planilha = work.getSheetAt(0);
	
				//pega as informacoes da primeira linha
				HSSFRow linha = planilha.getRow(0);
				Iterator<Cell> iterator = linha.cellIterator();
	
				posicaoColunas = new ArrayList<Obejto>();
	
				while(iterator.hasNext()){
					Cell celula = iterator.next();
	
					String conteudoCelula = celula.getStringCellValue();
	
					if(conteudoCelula == null || conteudoCelula.length() == 0){
						break;
					}
	
					System.out.println(posicaoColunas.size() + " - " + conteudoCelula);
					Obejto objetoColuna = new Obejto();
					objetoColuna.setPosicao(posicaoColunas.size());
					objetoColuna.setValor(conteudoCelula);
					
					posicaoColunas.add(objetoColuna);
				}
				
				mensagens.put("mensagem", Mensagens.PLANILHA_CARREGADA);
				apresentarMensagens();
	
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}else{
			return telaCargaUsuario();
		}
		
		return TELA_CONFIRMA_CARGA_USUARIO;
	}

	private boolean validaArquivo() {
		if(this.uploadFileName == null || this.uploadFileName.length() == 0){
			erros.put("erro", MensagensErro.CAMPO_OBRIGATORIO_NAO_INFORMADO);
			return false;
		}
		else if(!this.uploadFileName.contains(".xls")){
			erros.put("erro", MensagensErro.ARQUIVO_FORMATO_INVALIDO);
			return false;
		}
		
		return true;
	}

	/**
	 * Realiza a importação de todos os registros da planilha, atribuindo aos objetos
	 * Destinatario a serem persistidos no banco
	 * @return
	 * @throws IOException 
	 */
	public String confirmarAssociacao() throws IOException{
		setMenuAtual(MENU_CONTATOS);
		posicaoColunas = getPosicaoColunas();
		
		String nomeArquivo = (String) ActionContext.getContext().getSession().get("arquivo");
		
		planilhaInputStream = new FileInputStream(new File(nomeArquivo));
		HSSFWorkbook work;

		int totalRegistros = 0;
		
		try {
			work = new HSSFWorkbook(planilhaInputStream);
			HSSFSheet planilha = work.getSheetAt(0);

			Iterator<Row> iteratorLinha = planilha.iterator();
			HSSFRow primeiraLinha = planilha.getRow(0);

			totalRegistros = planilha.getLastRowNum();
			
			while(iteratorLinha.hasNext()){
				Row linha = iteratorLinha.next();

				if(!linha.equals(primeiraLinha)){
					Destinatario destinatario = new Destinatario();
					
					
					if(this.colunaTipoPessoa > -1){
						//aguardando definicao de como virá nas planilhas
					}
					
					if(this.colunaNome > -1){
						destinatario.setNome(lerCelulaPlanilha(linha, this.colunaNome));
					}
					
					if(this.colunaCPF > -1){
						if(linha.getCell(this.colunaCPF) != null){
							destinatario.setCpf(lerCelulaPlanilha(linha, this.colunaCPF));
						}
					}
					
					if(this.colunaEndereco > -1){
						destinatario.setEndereco(lerCelulaPlanilha(linha, this.colunaEndereco));
					}
					
					if(this.colunaPrefixoEndereco > -1){
						destinatario.setPrefixoEndereco(lerCelulaPlanilha(linha, this.colunaPrefixoEndereco));
					}

					if(this.colunaNumeroEndereco > - 1){
						destinatario.setNumeroEndereco(lerCelulaPlanilha(linha, this.colunaNumeroEndereco));
					}
					
					if(this.colunaCEP > -1){
						destinatario.setCep(lerCelulaPlanilha(linha, this.colunaCEP));
					}
					
					if(this.colunaCidade > -1){
						Cidade cidade = new Cidade();
						cidade.setNome(lerCelulaPlanilha(linha, this.colunaCidade));
						
						if(this.colunaUF > -1){
							String strUf = lerCelulaPlanilha(linha, this.colunaUF);
							UF uf = UF.newInstance(strUf.toUpperCase());
							
							cidade.setUf(uf);
						}
						destinatario.setCidade(cidade);
					}
					
					if(this.colunaCelular > -1 || this.colunaTelefone > -1){
						Set<Telefone> listaTelefones = new HashSet<Telefone>();
						
						if(this.colunaCelular > -1){
							Telefone celular = new Telefone();
							celular.setCelular(true);
							celular.setDestinatario(destinatario);
							celular.setNumero(lerCelulaPlanilha(linha, this.colunaCelular));
							
							if(this.colunaDDDCelular > -1){
								celular.setDdd(lerCelulaPlanilha(linha, this.colunaDDDCelular));
							}
							if(this.colunaDDICelular > -1){
								celular.setDdi(lerCelulaPlanilha(linha, this.colunaDDICelular));
							}
							
							listaTelefones.add(celular);							
						}
						
						if(this.colunaTelefone > -1){
							Telefone telefone = new Telefone();
							telefone.setCelular(false);
							telefone.setDestinatario(destinatario);
							telefone.setNumero(lerCelulaPlanilha(linha, this.colunaTelefone));
							
							if(this.colunaDDDTelefone > -1){
								telefone.setDdd(lerCelulaPlanilha(linha, this.colunaDDDTelefone));
							}
							if(this.colunaDDITelefone > - 1){
								telefone.setDdi(lerCelulaPlanilha(linha, this.colunaDDITelefone));
							}
							if(this.colunaRamalTelefone > - 1){
								telefone.setRamal(lerCelulaPlanilha(linha, this.colunaRamalTelefone));
							}
							
							listaTelefones.add(telefone);
						}
						
						destinatario.setTelefones(listaTelefones);
					}
					
					if(this.colunaEmail > -1){
						destinatario.setEmail(lerCelulaPlanilha(linha, this.colunaEmail));
					}
					if(this.colunaTratamento > -1){
						destinatario.setTratamento(lerCelulaPlanilha(linha, this.colunaTratamento));
					}
					if(this.colunaApelido > -1){
						destinatario.setApelido(lerCelulaPlanilha(linha, this.colunaApelido));
					}
					if(this.colunaSexo > -1){
						String strSexo = lerCelulaPlanilha(linha, this.colunaSexo);
						SEXO sexo = SEXO.newInstance(strSexo);
						destinatario.setSexo(sexo);
					}
					if(this.colunaRg > -1){
						destinatario.setRg(lerCelulaPlanilha(linha, this.colunaRg));
					}
					if(this.colunaDataNascimento > -1){
						if(linha.getCell(this.colunaDataNascimento).getCellType() != Cell.CELL_TYPE_STRING){
							destinatario.setDataNascimento(linha.getCell(this.colunaDataNascimento).getDateCellValue());
						}
					}
					if(this.colunaHomePage > -1){
						destinatario.setHomePage(lerCelulaPlanilha(linha, this.colunaHomePage));
					}
					if(this.colunaEmpresa > -1){
						destinatario.setEmpresa(lerCelulaPlanilha(linha, this.colunaEmpresa));
					}
					if(this.colunaCargo > -1){
						destinatario.setCargo(lerCelulaPlanilha(linha, this.colunaCargo));
					}
					if(this.colunaComplementoEndereco > -1){
						destinatario.setComplementoEndereco(lerCelulaPlanilha(linha, this.colunaComplementoEndereco));
					}
					if(this.colunaBairro > -1){
						destinatario.setBairro(lerCelulaPlanilha(linha, this.colunaBairro));
					}
					if(this.colunaPartidoPolitico > -1){
						destinatario.setPartidoPolitico(lerCelulaPlanilha(linha, this.colunaPartidoPolitico));
					}
					
					destinatario.setCliente(getUsuarioLogado().getCliente());
					getDestinatarioFacade().salvar(destinatario);
				}
			}
			
			File file = new File(nomeArquivo);
			if(file.exists()){
				file.delete();
				ActionContext.getContext().getSession().remove("arquivo");
			}
		
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			erros.put("erro", e.getMessage());
			return telaCargaUsuario();
		} catch (IllegalStateException illegal){
			illegal.printStackTrace();
			erros.put("erro", "Verifique se não atribuiu nenhuma coluna à algum campo errado.");
			return telaCargaUsuario();
		} catch (IOException e) {
			e.printStackTrace();
			erros.put("erro", e.getMessage());
			return telaCargaUsuario();
		}

		mensagens.put("mensagem", totalRegistros + " Registros importados com sucesso");
		return telaCargaUsuario();
	}


	/**
	 * Ler o conteúdo de uma célula e retorna uma string independente da formatação na planilha
	 * @param linha
	 * @param numeroColuna
	 * @return
	 */
	private String lerCelulaPlanilha(Row linha, int numeroColuna){
		String conteudo = "";
		
		if(linha.getCell(numeroColuna) != null){
			if(linha.getCell(numeroColuna).getCellType() == Cell.CELL_TYPE_NUMERIC){
			
				conteudo = String.valueOf(linha.getCell(numeroColuna).getNumericCellValue()); 
			} else if(linha.getCell(numeroColuna).getCellType() == Cell.CELL_TYPE_BLANK){
				conteudo = "";
			}
			else{
				conteudo = linha.getCell(numeroColuna).getStringCellValue();
			}
		}

		return conteudo;
	}
	
	@SuppressWarnings("unchecked")
	public List<Obejto> getPosicaoColunas() {
		Collections.sort(posicaoColunas);
		return posicaoColunas;
	}

	public void setPosicaoColunas(List<Obejto> posicaoColunas) {
		this.posicaoColunas = posicaoColunas;
	}

	public File getUpload() {
		return upload;
	}

	public void setUpload(File upload) {
		this.upload = upload;
	}


	public String getUploadFileName() {
		return uploadFileName;
	}

	public void setUploadFileName(String uploadFileName) {
		this.uploadFileName = uploadFileName;
	}

	public String getUploadContentType() {
		return uploadContentType;
	}

	public void setUploadContentType(String uploadContentType) {
		this.uploadContentType = uploadContentType;
	}

	public FileInputStream getPlanilhaInputStream() {
		return planilhaInputStream;
	}

	public void setPlanilhaInputStream(FileInputStream planilhaInputStream) {
		this.planilhaInputStream = planilhaInputStream;
	}

	public List<Obejto> getObejtos() {
		return obejtos;
	}

	public void setObejtos(List<Obejto> obejtos) {
		this.obejtos = obejtos;
	}

	public Integer getColunaNome() {
		return colunaNome;
	}

	public void setColunaNome(Integer colunaNome) {
		this.colunaNome = colunaNome;
	}

	public Integer getColunaCPF() {
		return colunaCPF;
	}

	public void setColunaCPF(Integer colunaCPF) {
		this.colunaCPF = colunaCPF;
	}

	public Integer getColunaCidade() {
		return colunaCidade;
	}

	public Integer getColunaEndereco() {
		return colunaEndereco;
	}

	public void setColunaEndereco(Integer colunaEndereco) {
		this.colunaEndereco = colunaEndereco;
	}

	public void setColunaCidade(Integer colunaCidade) {
		this.colunaCidade = colunaCidade;
	}

	public Integer getColunaUF() {
		return colunaUF;
	}

	public void setColunaUF(Integer colunaUF) {
		this.colunaUF = colunaUF;
	}

	public Integer getColunaTelefone() {
		return colunaTelefone;
	}

	public void setColunaTelefone(Integer colunaTelefone) {
		this.colunaTelefone = colunaTelefone;
	}

	public Integer getColunaCelular() {
		return colunaCelular;
	}

	public void setColunaCelular(Integer colunaCelular) {
		this.colunaCelular = colunaCelular;
	}

	public Integer getColunaEmail() {
		return colunaEmail;
	}

	public void setColunaEmail(Integer colunaEmail) {
		this.colunaEmail = colunaEmail;
	}

	public Integer getColunaTratamento() {
		return colunaTratamento;
	}

	public void setColunaTratamento(Integer colunaTratamento) {
		this.colunaTratamento = colunaTratamento;
	}

	public Integer getColunaApelido() {
		return colunaApelido;
	}

	public void setColunaApelido(Integer colunaApelido) {
		this.colunaApelido = colunaApelido;
	}

	public Integer getColunaSexo() {
		return colunaSexo;
	}

	public void setColunaSexo(Integer colunaSexo) {
		this.colunaSexo = colunaSexo;
	}

	public Integer getColunaRg() {
		return colunaRg;
	}

	public void setColunaRg(Integer colunaRg) {
		this.colunaRg = colunaRg;
	}

	public Integer getColunaDataNascimento() {
		return colunaDataNascimento;
	}

	public void setColunaDataNascimento(Integer colunaDataNascimento) {
		this.colunaDataNascimento = colunaDataNascimento;
	}

	public Integer getColunaHomePage() {
		return colunaHomePage;
	}

	public void setColunaHomePage(Integer colunaHomePage) {
		this.colunaHomePage = colunaHomePage;
	}

	public Integer getColunaEmpresa() {
		return colunaEmpresa;
	}

	public void setColunaEmpresa(Integer colunaEmpresa) {
		this.colunaEmpresa = colunaEmpresa;
	}

	public Integer getColunaCargo() {
		return colunaCargo;
	}

	public void setColunaCargo(Integer colunaCargo) {
		this.colunaCargo = colunaCargo;
	}

	public Integer getColunaComplementoEndereco() {
		return colunaComplementoEndereco;
	}

	public void setColunaComplementoEndereco(Integer colunaComplementoEndereco) {
		this.colunaComplementoEndereco = colunaComplementoEndereco;
	}

	public Integer getColunaBairro() {
		return colunaBairro;
	}

	public void setColunaBairro(Integer colunaBairro) {
		this.colunaBairro = colunaBairro;
	}

	public Integer getColunaPais() {
		return colunaPais;
	}

	public void setColunaPais(Integer colunaPais) {
		this.colunaPais = colunaPais;
	}

	public Integer getColunaPartidoPolitico() {
		return colunaPartidoPolitico;
	}

	public void setColunaPartidoPolitico(Integer colunaPartidoPolitico) {
		this.colunaPartidoPolitico = colunaPartidoPolitico;
	}

	public Integer getColunaTipoPessoa() {
		return colunaTipoPessoa;
	}

	public void setColunaTipoPessoa(Integer colunaTipoPessoa) {
		this.colunaTipoPessoa = colunaTipoPessoa;
	}

	public Integer getColunaPrefixoEndereco() {
		return colunaPrefixoEndereco;
	}

	public void setColunaPrefixoEndereco(Integer colunaPrefixoEndereco) {
		this.colunaPrefixoEndereco = colunaPrefixoEndereco;
	}

	public Integer getColunaNumeroEndereco() {
		return colunaNumeroEndereco;
	}

	public void setColunaNumeroEndereco(Integer colunaNumeroEndereco) {
		this.colunaNumeroEndereco = colunaNumeroEndereco;
	}

	public Integer getColunaDDDTelefone() {
		return colunaDDDTelefone;
	}

	public void setColunaDDDTelefone(Integer colunaDDDTelefone) {
		this.colunaDDDTelefone = colunaDDDTelefone;
	}

	public Integer getColunaDDITelefone() {
		return colunaDDITelefone;
	}

	public void setColunaDDITelefone(Integer colunaDDITelefone) {
		this.colunaDDITelefone = colunaDDITelefone;
	}

	public Integer getColunaRamalTelefone() {
		return colunaRamalTelefone;
	}

	public void setColunaRamalTelefone(Integer colunaRamalTelefone) {
		this.colunaRamalTelefone = colunaRamalTelefone;
	}

	public Integer getColunaDDDCelular() {
		return colunaDDDCelular;
	}

	public void setColunaDDDCelular(Integer colunaDDDCelular) {
		this.colunaDDDCelular = colunaDDDCelular;
	}

	public Integer getColunaDDICelular() {
		return colunaDDICelular;
	}

	public void setColunaDDICelular(Integer colunaDDICelular) {
		this.colunaDDICelular = colunaDDICelular;
	}

	public Integer getColunaCEP() {
		return colunaCEP;
	}

	public void setColunaCEP(Integer colunaCEP) {
		this.colunaCEP = colunaCEP;
	}
	
}
